package edu.usm.cs.roberge.views;

import java.util.ArrayList;
import java.util.List;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.table.AbstractTableModel;

import edu.usm.cs.roberge.NewsGroup;
import edu.usm.cs.roberge.NewsReaderModel;

/**
 * Implementation of a TableModel used by JTable
 * Essentially delegates most behavior to the application model
 * 
 * @author Dave Roberge
 */
public class NewsGroupTableModel extends AbstractTableModel {

	private static final long serialVersionUID = 1L;
	private final Icon nonFavorite = new ImageIcon("resources/non-favorite.png");
	private final Icon favorite = new ImageIcon("resources/favorite.png");
	private final NewsReaderModel dataModel;
	private boolean filtering;
	private final List<NewsGroup> filteringList = new ArrayList<NewsGroup>();
	
	public NewsGroupTableModel(NewsReaderModel dataModel) {
		this.dataModel = dataModel;
	}
	
	@Override
	public int getColumnCount() {
		return 3;
	}

	@Override
	public int getRowCount() {
		//return 0;
		if (filtering) {
			return filteringList.size();
		}
		return dataModel.getNewsGroupSize();
	}

	@Override
	public Object getValueAt(int arg0, int arg1) {
		NewsGroup valueFor = getNewsGroup(arg0);
		return getValueForColumn(arg1, valueFor);
	}

	private NewsGroup getNewsGroup(int arg0) {
		NewsGroup valueFor;
		if (filtering) {
			valueFor = filteringList.get(arg0);
		} else {
			valueFor = dataModel.getNewsGroup(arg0);
		}
		
		return valueFor;
	}

	private Object getValueForColumn(int columnIndex, NewsGroup valueFor) {
		switch(columnIndex) {
		case 0:
			return valueFor.isFavorite() ? favorite : nonFavorite;
		case 1:
			return valueFor.getNewsGroupName();
		case 2:
		default:
			return valueFor.getMessageCount();
		}
	}

	@Override
	public Class<?> getColumnClass(int arg0) {
		switch (arg0) {
		case 0:
			return Icon.class;
		case 1:
			return Object.class;
		case 2:
			return Integer.class;
		}		
		
		throw new IllegalArgumentException("Column index cannot be greater than 2");
	}
	
	@Override
	public String getColumnName(int columnIndex) {
		switch(columnIndex) {
		case 0:
			return "Favorite";
		case 1:
			return "News Group Name";
		case 2:
			return "Message Count";
		}
		
		throw new IllegalArgumentException("Column index cannot be greater than 2");
	}

	public void rowSelected(int selectedColumn, int selectedRow) {
		if (selectedColumn != 0 || selectedRow == -1 || selectedRow > newsGroupSize()) {
			return;
		}
		
		NewsGroup ng = getNewsGroup(selectedRow);
		ng.setFavorite(!ng.isFavorite());
		fireTableCellUpdated(selectedRow, selectedColumn);
	}

	private int newsGroupSize() {
		if (filtering) {
			return filteringList.size();
		}
		return dataModel.getNewsGroupSize();
	}

	/**
	 * Set a filter on the underlying news group data collection
	 * @param text the filter to apply
	 */
	public void setFilter(String text) {
		if (text == null || text.isEmpty()) {
			filtering = false;
			return;
		}
		
		filtering = true;
		filteringList.clear();
		for(NewsGroup ng : dataModel.getNewsGroups()) {
			if (ng.getNewsGroupName().contains(text)) {
				filteringList.add(ng);
			}
		}
		fireTableDataChanged();
	}
}
